/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package net.stuffrepos.bricknetcenter.database.schema;

import java.io.Serializable;
import java.util.LinkedList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.annotations.GenericGenerator;

/**
 *
 * @author Eduardo H. Bogoni <eduardobogoni@gmail.com>
 */
@Entity
@Table(name = "informations")
@Inheritance(strategy = InheritanceType.JOINED)
public class Information implements Serializable {

    private static final Log log = LogFactory.getLog(Information.class);

    @Id
    @GeneratedValue(generator = "system-uuid")
    @GenericGenerator(name = "system-uuid", strategy = "uuid")
    @Column(length = 32)
    private String id;
    @ManyToOne
    private Information parent;
    @Column
    @Enumerated(EnumType.STRING)
    private Type type;
    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)
    private List<Information> informations = new LinkedList<Information>();
    @Column(length = Short.MAX_VALUE)
    private String value;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public Information getParent() {
        return parent;
    }

    public void setParent(Information parent) {
        if (this.parent != null && this.parent != parent) {
            this.parent.getInformations().remove(this);
        }

        this.parent = parent;
        if (parent != null) {
            parent.getInformations().add(this);
        }
    }

    public Type getType() {
        return type;
    }

    public void setType(Type type) {
        this.type = type;
    }

    public List<Information> getInformations() {
        return informations;
    }

    public void setInformations(List<Information> informations) {
        this.informations = informations;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public Information getFirstChild(Type type) {
        for (Information child : getInformations()) {
            if (type.equals(child.getType())) {
                return child;
            }
        }

        return null;
    }

    public static enum Type {

        Provider,
        Set,
        Parts,
        Minifigs,
        Year,
        Name,
        Theme,
        Part,
        Color,
        Quantity,
        Note,
        Image,
        Group,
        SetPart,
        Minifig,
        Book,
        UnsortedLot,
        OriginalBox,
        Instruction,
        Gear,
        Catalog,
        ItemType,
        Category,
        Weight,
        DimensionZ,
        DimensionY,
        DimensionX
    }

    public String getDn() {
        String current = type + "=" + value;
        if (parent == null) {
            return current;
        } else {
            return current + "," + parent.getDn();
        }
    }

    @Override
    public String toString() {
        log.trace("Requested Information.toString()");
        return type + ": " + value;
    }
}
